import type { Setting } from './config'
import flatpickr from 'flatpickr'
import Mandarin from 'flatpickr/dist/l10n/zh.js'
import $ from 'jquery'
import defaultSetting from './config'
import { luckysheetlodingHTML } from './controllers/constant.js'
import { initPlugins } from './controllers/expendPlugins.js'
import { initialFilterHandler } from './controllers/filter.js'
import { formulaBarInitial } from './controllers/formulaBar.js'
import luckysheetHandler from './controllers/handler.js'
import { keyboardInitial } from './controllers/keyboard.js'
import { initListener } from './controllers/listener.js'
import { initialMatrixOperation } from './controllers/matrixOperation.js'
import { orderByInitial } from './controllers/orderBy.js'
import { printInitial } from './controllers/print.js'
import { rowColumnOperationInitial } from './controllers/rowColumnOperation.js'
import { selectHightlightShow } from './controllers/select.js'
import server from './controllers/server.js'
import { initialSheetBar } from './controllers/sheetBar.js'
import sheetConfigsetting from './controllers/sheetConfigsetting.js'
import sheetmanage from './controllers/sheetmanage.js'
import { zoomInitial } from './controllers/zoom.js'
import functionlist from './function/functionlist.js'
import * as api from './global/api.js'
import {
  exportSheetBlob,
  exportSheetBuffer,
  exportSheetExcel,
} from './global/exportSheet.js'
import { luckysheetextendData } from './global/extend.js'
import { getcellvalue, getdatabyselection } from './global/getdata.js'
import { hideloading, showloading } from './global/loading.js'

import method from './global/method.js'

import { getOptions } from './global/options.js'
import { jfrefreshgrid, luckysheetrefreshgrid } from './global/refresh.js'
import { setcellvalue } from './global/setdata.js'
import { locales } from './locale/locale.js'
import {
  getconfig,
  getluckysheet_select_save,
  getluckysheetfile,
} from './methods/get.js'

import { setluckysheet_select_save } from './methods/set.js'
import Store from './store/index.js'
import { common_extend } from './utils/util.js'
import 'spectrum-colorpicker/spectrum.css'

export type { Setting } from './config'

export type WindowSingle = Window & typeof globalThis & {
  luckysheet?: unknown
  $: JQueryStatic
}

// 全局注册 jquery
if (!(window as WindowSingle)?.$) {
  (window as WindowSingle).$ = $
}

// 创建luckysheet表格
function create(setting: Setting) {
  method.destroy()
  // Store original parameters for api: toJson
  Store.toJsonOptions = {
    ...(setting || {}),
    data: undefined,
  }

  const extendsetting = common_extend(defaultSetting, setting)

  const loadurl = extendsetting.loadUrl
  const menu = extendsetting.menu
  const title = extendsetting.title

  const container = extendsetting.container
  Store.container = container
  Store.luckysheetfile = extendsetting.data
  Store.defaultcolumnNum = extendsetting.column
  Store.defaultrowNum = extendsetting.row
  Store.defaultFontSize = extendsetting.defaultFontSize
  Store.fullscreenmode = extendsetting.fullscreenmode
  Store.lang = extendsetting.lang // language
  Store.allowEdit = extendsetting.allowEdit
  Store.limitSheetNameLength = extendsetting.limitSheetNameLength
  Store.defaultSheetNameMaxLength = extendsetting.defaultSheetNameMaxLength
  Store.fontList = extendsetting.fontList
  server.gridKey = extendsetting.gridKey
  server.loadUrl = extendsetting.loadUrl
  server.updateUrl = extendsetting.updateUrl
  server.updateImageUrl = extendsetting.updateImageUrl
  server.title = extendsetting.title
  server.loadSheetUrl = extendsetting.loadSheetUrl
  server.allowUpdate = extendsetting.allowUpdate

  sheetConfigsetting.autoFormatw = extendsetting.autoFormatw
  sheetConfigsetting.accuracy = extendsetting.accuracy
  sheetConfigsetting.total = extendsetting?.data?.[0]?.total

  sheetConfigsetting.loading = extendsetting.loading
  sheetConfigsetting.allowCopy = extendsetting.allowCopy
  sheetConfigsetting.showtoolbar = extendsetting.showtoolbar
  sheetConfigsetting.showtoolbarConfig = extendsetting.showtoolbarConfig
  sheetConfigsetting.showinfobar = extendsetting.showinfobar
  sheetConfigsetting.showsheetbar = extendsetting.showsheetbar
  sheetConfigsetting.showsheetbarConfig = extendsetting.showsheetbarConfig
  sheetConfigsetting.showstatisticBar = extendsetting.showstatisticBar
  sheetConfigsetting.showstatisticBarConfig
    = extendsetting.showstatisticBarConfig
  sheetConfigsetting.sheetFormulaBar = extendsetting.sheetFormulaBar
  sheetConfigsetting.cellRightClickConfig
    = extendsetting.cellRightClickConfig
  sheetConfigsetting.sheetRightClickConfig
    = extendsetting.sheetRightClickConfig
  sheetConfigsetting.pointEdit = extendsetting.pointEdit
  sheetConfigsetting.pointEditUpdate = extendsetting.pointEditUpdate
  sheetConfigsetting.pointEditZoom = extendsetting.pointEditZoom

  sheetConfigsetting.userInfo = extendsetting.userInfo
  sheetConfigsetting.userMenuItem = extendsetting.userMenuItem
  sheetConfigsetting.myFolderUrl = extendsetting.myFolderUrl
  sheetConfigsetting.functionButton = extendsetting.functionButton

  sheetConfigsetting.showConfigWindowResize
    = extendsetting.showConfigWindowResize
  sheetConfigsetting.enableAddRow = extendsetting.enableAddRow
  sheetConfigsetting.enableAddBackTop = extendsetting.enableAddBackTop
  sheetConfigsetting.addRowCount = extendsetting.addRowCount
  sheetConfigsetting.enablePage = extendsetting.enablePage
  sheetConfigsetting.pageInfo = extendsetting.pageInfo

  sheetConfigsetting.editMode = extendsetting.editMode
  sheetConfigsetting.beforeCreateDom = extendsetting.beforeCreateDom
  sheetConfigsetting.workbookCreateBefore
    = extendsetting.workbookCreateBefore
  sheetConfigsetting.workbookCreateAfter
    = extendsetting.workbookCreateAfter
  sheetConfigsetting.remoteFunction = extendsetting.remoteFunction
  sheetConfigsetting.customFunctions = extendsetting.customFunctions

  sheetConfigsetting.fireMousedown = extendsetting.fireMousedown
  sheetConfigsetting.forceCalculation = extendsetting.forceCalculation
  sheetConfigsetting.plugins = extendsetting.plugins

  sheetConfigsetting.rowHeaderWidth = extendsetting.rowHeaderWidth
  sheetConfigsetting.columnHeaderHeight = extendsetting.columnHeaderHeight

  sheetConfigsetting.defaultColWidth = extendsetting.defaultColWidth
  sheetConfigsetting.defaultRowHeight = extendsetting.defaultRowHeight

  sheetConfigsetting.title = extendsetting.title
  sheetConfigsetting.container = extendsetting.container
  sheetConfigsetting.hook = extendsetting.hook

  sheetConfigsetting.pager = extendsetting.pager

  sheetConfigsetting.initShowsheetbarConfig = false

  sheetConfigsetting.imageUpdateMethodConfig
    = extendsetting.imageUpdateMethodConfig

  if (Store.lang === 'zh' && Mandarin.zh)
    flatpickr.localize(Mandarin.zh)

  // Store the currently used plugins for monitoring asynchronous loading
  Store.asyncLoad.push(...sheetConfigsetting.plugins)

  // Register plugins
  initPlugins(extendsetting.plugins, extendsetting.data)

  // Store formula information, including internationalization
  functionlist(extendsetting.customFunctions)

  let devicePixelRatio = extendsetting.devicePixelRatio
  if (devicePixelRatio == null) {
    devicePixelRatio = 1
  }
  Store.devicePixelRatio = Math.ceil(devicePixelRatio)

  // loading
  const loadingObj = luckysheetlodingHTML(`#${container}`)!
  Store.loadingObj = loadingObj

  if (loadurl === '') {
    sheetmanage.initialjfFile(menu, title)
    // luckysheetsizeauto();
    initialWorkBook()
  }
  else {
    $.post(loadurl, { gridKey: server.gridKey }, (d) => {
      // eslint-disable-next-line no-new-func
      const data = new Function(`return ${d}`)()
      Store.luckysheetfile = data

      sheetmanage.initialjfFile(menu, title)
      // luckysheetsizeauto();
      initialWorkBook()

      // 需要更新数据给后台时，建立WebSocket连接
      if (server.allowUpdate) {
        server.openWebSocket()
      }
    })
  }
}

function initialWorkBook() {
  luckysheetHandler() // Overall dom initialization
  initialFilterHandler() // Filter initialization
  initialMatrixOperation() // Right click matrix initialization
  initialSheetBar() // bottom sheet bar initialization
  formulaBarInitial() // top formula bar initialization
  rowColumnOperationInitial() // row and coloumn operate initialization
  keyboardInitial() // Keyboard operate initialization
  orderByInitial() // menu bar orderby function initialization
  zoomInitial() // zoom method initialization
  printInitial() // print initialization
  initListener()
}

export const luckysheet = {
  ...(common_extend(api, {})) as object,
  create,
  /**
   * 获取所有表格数据
   */
  getluckysheetfile,
  /**
   * 获取当前表格 选区
   */
  getluckysheet_select_save,
  /**
   * 设置当前表格
   */
  setluckysheet_select_save,
  /**
   * 获取当前表格 config配置
   */
  getconfig,
  /**
   * 二维数组数据 转化成 {r, c, v}格式 一维数组 (传入参数为二维数据data)
   */
  getGridData: sheetmanage.getGridData,
  /**
   * 生成表格所需二维数组 （传入参数为表格数据对象file）
   */
  buildGridData: sheetmanage.buildGridData,
  /**
   * Refresh the canvas display data according to scrollHeight and scrollWidth
   */
  luckysheetrefreshgrid,
  /**
   * Refresh canvas
   */
  jfrefreshgrid,
  /**
   * Get the value of the cell
   */
  getcellvalue,
  /**
   * Set cell value
   */
  setcellvalue,
  /**
   * Get selection range value
   */
  getdatabyselection,
  /**
   * sheetmanage
   */
  sheetmanage,
  /**
   * Data of the current table
   */
  flowdata: () => Store.flowdata,
  /**
   *  Set selection highlight
   */
  selectHightlightShow,
  /**
   * Reset parameters after destroying the table
   */
  destroy: method.destroy,
  /**
   * Get
   */
  showLoadingProgress: showloading,
  /**
   * Get
   */
  hideLoadingProgress: hideloading,
  /**
   * Get
   */
  luckysheetextendData,
  /**
   * 导出为 excel
   */
  exportSheetExcel,
  /**
   * 导出为 Blob
   */
  exportSheetBlob,
  /**
   * 导出为 ArrayBuffer
   */
  exportSheetBuffer,
  /**
   * 获取表格所有配置信息
   */
  getOptions,
  locales,

};

(window as WindowSingle).luckysheet = luckysheet
